Code coverage report for ./src/ocLazyLoad.loaders.core.js

Statements: 81.9% (95 / 116)      Branches: 72.92% (70 / 96)      Functions: 100% (19 / 19)      Lines: 81.9% (95 / 116)      Ignored: none     

All files » ./src/ » ocLazyLoad.loaders.core.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237    1     1 29             28 21   21             21   21   21 21   21 1 1   21 21     20   1 1     20 18   18                   20 3 17 4 13 13       1 1       21 2   19 19       21 3 3 3 1 1   2     3     21 4 4 4 1 1   3     4     21 13 13 13 1 1   12     13     21           21 1 1     20 20 20                     28 25   25             25 25     25   5 10       5 4   1     5       20 16 16 16       4   4 1       3       20               20                       20     20       20 17 16   1     3     20       28        
'use strict';
 
(function (angular) {
    'use strict';
 
    angular.module('oc.lazyLoad').config(function ($provide) {
        $provide.decorator('$ocLazyLoad', function ($delegate, $q) {
            /**
             * The function that loads new files
             * @param config
             * @param params
             * @returns {*}
             */
            $delegate.filesLoader = function filesLoader(config) {
                var params = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
 
                var cssFiles = [],
                    templatesFiles = [],
                    jsFiles = [],
                    promises = [],
                    cachePromise = null,
                    filesCache = $delegate._getFilesCache();
 
                $delegate.toggleWatch(true); // start watching angular.module calls
 
                angular.extend(params, config);
 
                var pushFile = function pushFile(path) {
                    var file_type = null,
                        m;
                    if (angular.isObject(path)) {
                        file_type = path.type;
                        path = path.path;
                    }
                    cachePromise = filesCache.get(path);
                    if (angular.isUndefined(cachePromise) || params.cache === false) {
 
                        // always check for requirejs syntax just in case
                        if ((m = /^(css|less|html|htm|js)?(?=!)/.exec(path)) !== null) {
                            // Detect file type using preceding type declaration (ala requireJS)
                            file_type = m[1];
                            path = path.substr(m[1].length + 1, path.length); // Strip the type from the path
                        }
 
                        if (!file_type) {
                            Eif ((m = /[.](css|less|html|htm|js)?((\?|#).*)?$/.exec(path)) !== null) {
                                // Detect file type via file extension
                                file_type = m[1];
                            } else if (!$delegate.jsLoader.hasOwnProperty('ocLazyLoadLoader') && $delegate.jsLoader.hasOwnProperty('requirejs')) {
                                // requirejs
                                file_type = 'js';
                            } else {
                                $delegate._$log.error('File type could not be determined. ' + path);
                                return;
                            }
                        }
 
                        if ((file_type === 'css' || file_type === 'less') && cssFiles.indexOf(path) === -1) {
                            cssFiles.push(path);
                        } else if ((file_type === 'html' || file_type === 'htm') && templatesFiles.indexOf(path) === -1) {
                            templatesFiles.push(path);
                        } else Eif (file_type === 'js' || jsFiles.indexOf(path) === -1) {
                            jsFiles.push(path);
                        } else {
                            $delegate._$log.error('File type is not valid. ' + path);
                        }
                    } else Eif (cachePromise) {
                        promises.push(cachePromise);
                    }
                };
 
                if (params.serie) {
                    pushFile(params.files.shift());
                } else {
                    angular.forEach(params.files, function (path) {
                        pushFile(path);
                    });
                }
 
                if (cssFiles.length > 0) {
                    var cssDeferred = $q.defer();
                    $delegate.cssLoader(cssFiles, function (err) {
                        if (angular.isDefined(err) && $delegate.cssLoader.hasOwnProperty('ocLazyLoadLoader')) {
                            $delegate._$log.error(err);
                            cssDeferred.reject(err);
                        } else {
                            cssDeferred.resolve();
                        }
                    }, params);
                    promises.push(cssDeferred.promise);
                }
 
                if (templatesFiles.length > 0) {
                    var templatesDeferred = $q.defer();
                    $delegate.templatesLoader(templatesFiles, function (err) {
                        if (angular.isDefined(err) && $delegate.templatesLoader.hasOwnProperty('ocLazyLoadLoader')) {
                            $delegate._$log.error(err);
                            templatesDeferred.reject(err);
                        } else {
                            templatesDeferred.resolve();
                        }
                    }, params);
                    promises.push(templatesDeferred.promise);
                }
 
                if (jsFiles.length > 0) {
                    var jsDeferred = $q.defer();
                    $delegate.jsLoader(jsFiles, function (err) {
                        if (angular.isDefined(err) && ($delegate.jsLoader.hasOwnProperty("ocLazyLoadLoader") || $delegate.jsLoader.hasOwnProperty("requirejs"))) {
                            $delegate._$log.error(err);
                            jsDeferred.reject(err);
                        } else {
                            jsDeferred.resolve();
                        }
                    }, params);
                    promises.push(jsDeferred.promise);
                }
 
                Iif (promises.length === 0) {
                    var deferred = $q.defer(),
                        err = "Error: no file to load has been found, if you're trying to load an existing module you should use the 'inject' method instead of 'load'.";
                    $delegate._$log.error(err);
                    deferred.reject(err);
                    return deferred.promise;
                } else if (params.serie && params.files.length > 0) {
                    return $q.all(promises).then(function () {
                        return $delegate.filesLoader(config, params);
                    });
                } else {
                    return $q.all(promises)['finally'](function (res) {
                        $delegate.toggleWatch(false); // stop watching angular.module calls
                        return res;
                    });
                }
            };
 
            /**
             * Load a module or a list of modules into Angular
             * @param module Mixed the name of a predefined module config object, or a module config object, or an array of either
             * @param params Object optional parameters
             * @returns promise
             */
            $delegate.load = function (originalModule) {
                var originalParams = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
 
                var self = this,
                    config = null,
                    deferredList = [],
                    deferred = $q.defer(),
                    errText;
 
                // clean copy
                var module = angular.copy(originalModule);
                var params = angular.copy(originalParams);
 
                // If module is an array, break it down
                if (angular.isArray(module)) {
                    // Resubmit each entry as a single module
                    angular.forEach(module, function (m) {
                        deferredList.push(self.load(m, params));
                    });
 
                    // Resolve the promise once everything has loaded
                    $q.all(deferredList).then(function (res) {
                        deferred.resolve(res);
                    }, function (err) {
                        deferred.reject(err);
                    });
 
                    return deferred.promise;
                }
 
                // Get or Set a configuration depending on what was passed in
                if (angular.isString(module)) {
                    config = self.getModuleConfig(module);
                    Eif (!config) {
                        config = {
                            files: [module]
                        };
                    }
                } else Eif (angular.isObject(module)) {
                    // case {type: 'js', path: lazyLoadUrl + 'testModule.fakejs'}
                    if (angular.isDefined(module.path) && angular.isDefined(module.type)) {
                        config = {
                            files: [module]
                        };
                    } else {
                        config = self.setModuleConfig(module);
                    }
                }
 
                Iif (config === null) {
                    var moduleName = self._getModuleName(module);
                    errText = 'Module "' + (moduleName || 'unknown') + '" is not configured, cannot load.';
                    $delegate._$log.error(errText);
                    deferred.reject(new Error(errText));
                    return deferred.promise;
                } else {
                    // deprecated
                    Iif (angular.isDefined(config.template)) {
                        if (angular.isUndefined(config.files)) {
                            config.files = [];
                        }
                        if (angular.isString(config.template)) {
                            config.files.push(config.template);
                        } else if (angular.isArray(config.template)) {
                            config.files.concat(config.template);
                        }
                    }
                }
 
                var localParams = angular.extend({}, params, config);
 
                // if someone used an external loader and called the load function with just the module name
                Iif (angular.isUndefined(config.files) && angular.isDefined(config.name) && $delegate.moduleExists(config.name)) {
                    return $delegate.inject(config.name, localParams, true);
                }
 
                $delegate.filesLoader(config, localParams).then(function () {
                    $delegate.inject(null, localParams).then(function (res) {
                        deferred.resolve(res);
                    }, function (err) {
                        deferred.reject(err);
                    });
                }, function (err) {
                    deferred.reject(err);
                });
 
                return deferred.promise;
            };
 
            // return the patched service
            return $delegate;
        });
    });
})(angular);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkM6L3dhbXAvd3d3L29jTGF6eUxvYWQvc3JjL29jTGF6eUxvYWQubG9hZGVycy5jb3JlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsQ0FBQyxVQUFBLE9BQU8sRUFBSTtBQUNSLGdCQUFZLENBQUM7O0FBRWIsV0FBTyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLENBQUMsVUFBUyxRQUFRLEVBQUU7QUFDcEQsZ0JBQVEsQ0FBQyxTQUFTLENBQUMsYUFBYSxFQUFFLFVBQVMsU0FBUyxFQUFFLEVBQUUsRUFBRTs7Ozs7OztBQU90RCxxQkFBUyxDQUFDLFdBQVcsR0FBRyxTQUFTLFdBQVcsQ0FBQyxNQUFNLEVBQWU7b0JBQWIsTUFBTSx5REFBRyxFQUFFOztBQUM1RCxvQkFBSSxRQUFRLEdBQUcsRUFBRTtvQkFDYixjQUFjLEdBQUcsRUFBRTtvQkFDbkIsT0FBTyxHQUFHLEVBQUU7b0JBQ1osUUFBUSxHQUFHLEVBQUU7b0JBQ2IsWUFBWSxHQUFHLElBQUk7b0JBQ25CLFVBQVUsR0FBRyxTQUFTLENBQUMsY0FBYyxFQUFFLENBQUM7O0FBRTVDLHlCQUFTLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDOztBQUU1Qix1QkFBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7O0FBRS9CLG9CQUFJLFFBQVEsR0FBRyxTQUFYLFFBQVEsQ0FBWSxJQUFJLEVBQUU7QUFDMUIsd0JBQUksU0FBUyxHQUFHLElBQUk7d0JBQUUsQ0FBQyxDQUFDO0FBQ3hCLHdCQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUU7QUFDdkIsaUNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQ3RCLDRCQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztxQkFDcEI7QUFDRCxnQ0FBWSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDcEMsd0JBQUcsT0FBTyxDQUFDLFdB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enlMb2FkL3NyYy9vY0xhenlMb2FkLmxvYWRlcnMuY29yZS5qcyIsInNvdXJjZXNDb250ZW50IjpbIihhbmd1bGFyID0+IHtcclxuICAgICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgICBhbmd1bGFyLm1vZHVsZSgnb2MubGF6eUxvYWQnKS5jb25maWcoZnVuY3Rpb24oJHByb3ZpZGUpIHtcclxuICAgICAgICAkcHJvdmlkZS5kZWNvcmF0b3IoJyRvY0xhenlMb2FkJywgZnVuY3Rpb24oJGRlbGVnYXRlLCAkcSkge1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGhlIGZ1bmN0aW9uIHRoYXQgbG9hZHMgbmV3IGZpbGVzXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBjb25maWdcclxuICAgICAgICAgICAgICogQHBhcmFtIHBhcmFtc1xyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn1cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICRkZWxlZ2F0ZS5maWxlc0xvYWRlciA9IGZ1bmN0aW9uIGZpbGVzTG9hZGVyKGNvbmZpZywgcGFyYW1zID0ge30pIHtcclxuICAgICAgICAgICAgICAgIHZhciBjc3NGaWxlcyA9IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlc0ZpbGVzID0gW10sXHJcbiAgICAgICAgICAgICAgICAgICAganNGaWxlcyA9IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VzID0gW10sXHJcbiAgICAgICAgICAgICAgICAgICAgY2FjaGVQcm9taXNlID0gbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICBmaWxlc0NhY2hlID0gJGRlbGVnYXRlLl9nZXRGaWxlc0NhY2hlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgJGRlbGVnYXRlLnRvZ2dsZVdhdGNoKHRydWUpOyAvLyBzdGFydCB3YXRjaGluZyBhbmd1bGFyLm1vZHVsZSBjYWxsc1xyXG5cclxuICAgICAgICAgICAgICAgIGFuZ3VsYXIuZXh0ZW5kKHBhcmFtcywgY29uZmlnKTtcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgcHVzaEZpbGUgPSBmdW5jdGlvbihwYXRoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbGVfdHlwZSA9IG51bGwsIG07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYoYW5ndWxhci5pc09iamVjdChwYXRoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxlX3R5cGUgPSBwYXRoLnR5cGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoLnBhdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhY2hlUHJvbWlzZSA9IGZpbGVzQ2FjaGUuZ2V0KHBhdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmKGFuZ3VsYXIuaXNVbmRlZmluZWQoY2FjaGVQcm9taXNlKSB8fCBwYXJhbXMuY2FjaGUgPT09IGZhbHNlKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbHdheXMgY2hlY2sgZm9yIHJlcXVpcmVqcyBzeW50YXgganVzdCBpbiBjYXNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmKChtID0gL14oY3NzfGxlc3N8aHRtbHxodG18anMpPyg/PSEpLy5leGVjKHBhdGgpKSAhPT0gbnVsbCkgeyAvLyBEZXRlY3QgZmlsZSB0eXBlIHVzaW5nIHByZWNlZGluZyB0eXBlIGRlY2xhcmF0aW9uIChhbGEgcmVxdWlyZUpTKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV90eXBlID0gbVsxXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoLnN1YnN0cihtWzFdLmxlbmd0aCArIDEsIHBhdGgubGVuZ3RoKTsgIC8vIFN0cmlwIHRoZSB0eXBlIGZyb20gdGhlIHBhdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoIWZpbGVfdHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoKG0gPSAvWy5dKGNzc3xsZXNzfGh0bWx8aHRtfGpzKT8oKFxcP3wjKS4qKT8kLy5leGVjKHBhdGgpKSAhPT0gbnVsbCkgeyAgLy8gRGV0ZWN0IGZpbGUgdHlwZSB2aWEgZmlsZSBleHRlbnNpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlX3R5cGUgPSBtWzFdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKCEkZGVsZWdhdGUuanNMb2FkZXIuaGFzT3duUHJvcGVydHkoJ29jTGF6eUxvYWRMb2FkZXInKSAmJiAkZGVsZWdhdGUuanNMb2FkZXIuaGFzT3duUHJvcGVydHkoJ3JlcXVpcmVqcycpKSB7IC8vIHJlcXVpcmVqc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfdHlwZSA9ICdqcyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkZWxlZ2F0ZS5fJGxvZy5lcnJvcihgRmlsZSB0eXBlIGNvdWxkIG5vdCBiZSBkZXRlcm1pbmVkLiAkeyBwYXRoIH1gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmKChmaWxlX3R5cGUgPT09ICdjc3MnIHx8IGZpbGVfdHlwZSA9PT0gJ2xlc3MnKSAmJiBjc3NGaWxlcy5pbmRleE9mKHBhdGgpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzRmlsZXMucHVzaChwYXRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKChmaWxlX3R5cGUgPT09ICdodG1sJyB8fCBmaWxlX3R5cGUgPT09ICdodG0nKSAmJiB0ZW1wbGF0ZXNGaWxlcy5pbmRleE9mKHBhdGgpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVzRmlsZXMucHVzaChwYXRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKGZpbGVfdHlwZSA9PT0gJ2pzJyB8fCBqc0ZpbGVzLmluZGV4T2YocGF0aCkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc0ZpbGVzLnB1c2gocGF0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZGVsZWdhdGUuXyRsb2cuZXJyb3IoYEZpbGUgdHlwZSBpcyBub3QgdmFsaWQuICR7IHBhdGggfWApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZihjYWNoZVByb21pc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChjYWNoZVByb21pc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgaWYocGFyYW1zLnNlcmllKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHVzaEZpbGUocGFyYW1zLmZpbGVzLnNoaWZ0KCkpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBhbmd1bGFyLmZvckVhY2gocGFyYW1zLmZpbGVzLCBwYXRoID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHVzaEZpbGUocGF0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYoY3NzRmlsZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjc3NEZWZlcnJlZCA9ICRxLmRlZmVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgJGRlbGVnYXRlLmNzc0xvYWRlcihjc3NGaWxlcywgZXJyID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoYW5ndWxhci5pc0RlZmluZWQoZXJyKSAmJiAkZGVsZWdhdGUuY3NzTG9hZGVyLmhhc093blByb3BlcnR5KCdvY0xhenlMb2FkTG9hZGVyJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkZWxlZ2F0ZS5fJGxvZy5lcnJvcihlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzRGVmZXJyZWQucmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NEZWZlcnJlZC5yZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9LCBwYXJhbXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goY3NzRGVmZXJyZWQucHJvbWlzZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYodGVtcGxhdGVzRmlsZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZW1wbGF0ZXNEZWZlcnJlZCA9ICRxLmRlZmVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgJGRlbGVnYXRlLnRlbXBsYXRlc0xvYWRlcih0ZW1wbGF0ZXNGaWxlcywgZXJyID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoYW5ndWxhci5pc0RlZmluZWQoZXJyKSAmJiAkZGVsZWdhdGUudGVtcGxhdGVzTG9hZGVyLmhhc093blByb3BlcnR5KCdvY0xhenlMb2FkTG9hZGVyJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkZWxlZ2F0ZS5fJGxvZy5lcnJvcihlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVzRGVmZXJyZWQucmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZXNEZWZlcnJlZC5yZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9LCBwYXJhbXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGVtcGxhdGVzRGVmZXJyZWQucHJvbWlzZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYoanNGaWxlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGpzRGVmZXJyZWQgPSAkcS5kZWZlcigpO1xyXG4gICAgICAgICAgICAgICAgICAgICRkZWxlZ2F0ZS5qc0xvYWRlcihqc0ZpbGVzLCBlcnIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihhbmd1bGFyLmlzRGVmaW5lZChlcnIpICYmICgkZGVsZWdhdGUuanNMb2FkZXIuaGFzT3duUHJvcGVydHkoXCJvY0xhenlMb2FkTG9hZGVyXCIpIHx8ICRkZWxlZ2F0ZS5qc0xvYWRlci5oYXNPd25Qcm9wZXJ0eShcInJlcXVpcmVqc1wiKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRkZWxlZ2F0ZS5fJGxvZy5lcnJvcihlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAganNEZWZlcnJlZC5yZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzRGVmZXJyZWQucmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgcGFyYW1zKTtcclxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKGpzRGVmZXJyZWQucHJvbWlzZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYocHJvbWlzZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGRlZmVycmVkID0gJHEuZGVmZXIoKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyID0gXCJFcnJvcjogbm8gZmlsZSB0byBsb2FkIGhhcyBiZWVuIGZvdW5kLCBpZiB5b3UncmUgdHJ5aW5nIHRvIGxvYWQgYW4gZXhpc3RpbmcgbW9kdWxlIHlvdSBzaG91bGQgdXNlIHRoZSAnaW5qZWN0JyBtZXRob2QgaW5zdGVhZCBvZiAnbG9hZCcuXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgJGRlbGVnYXRlLl8kbG9nLmVycm9yKGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYocGFyYW1zLnNlcmllICYmIHBhcmFtcy5maWxlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRxLmFsbChwcm9taXNlcykudGhlbigoKSA9PiAkZGVsZWdhdGUuZmlsZXNMb2FkZXIoY29uZmlnLCBwYXJhbXMpKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRxLmFsbChwcm9taXNlcykuZmluYWxseShyZXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAkZGVsZWdhdGUudG9nZ2xlV2F0Y2goZmFsc2UpOyAvLyBzdG9wIHdhdGNoaW5nIGFuZ3VsYXIubW9kdWxlIGNhbGxzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTG9hZCBhIG1vZHVsZSBvciBhIGxpc3Qgb2YgbW9kdWxlcyBpbnRvIEFuZ3VsYXJcclxuICAgICAgICAgICAgICogQHBhcmFtIG1vZHVsZSBNaXhlZCB0aGUgbmFtZSBvZiBhIHByZWRlZmluZWQgbW9kdWxlIGNvbmZpZyBvYmplY3QsIG9yIGEgbW9kdWxlIGNvbmZpZyBvYmplY3QsIG9yIGFuIGFycmF5IG9mIGVpdGhlclxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gcGFyYW1zIE9iamVjdCBvcHRpb25hbCBwYXJhbWV0ZXJzXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHByb21pc2VcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICRkZWxlZ2F0ZS5sb2FkID0gZnVuY3Rpb24ob3JpZ2luYWxNb2R1bGUsIG9yaWdpbmFsUGFyYW1zID0ge30pIHtcclxuICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICAgICAgICAgICAgICBjb25maWcgPSBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgIGRlZmVycmVkTGlzdCA9IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIGRlZmVycmVkID0gJHEuZGVmZXIoKSxcclxuICAgICAgICAgICAgICAgICAgICBlcnJUZXh0O1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIGNsZWFuIGNvcHlcclxuICAgICAgICAgICAgICAgIHZhciBtb2R1bGUgPSBhbmd1bGFyLmNvcHkob3JpZ2luYWxNb2R1bGUpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHBhcmFtcyA9IGFuZ3VsYXIuY29weShvcmlnaW5hbFBhcmFtcyk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gSWYgbW9kdWxlIGlzIGFuIGFycmF5LCBicmVhayBpdCBkb3duXHJcbiAgICAgICAgICAgICAgICBpZihhbmd1bGFyLmlzQXJyYXkobW9kdWxlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc3VibWl0IGVhY2ggZW50cnkgYXMgYSBzaW5nbGUgbW9kdWxlXHJcbiAgICAgICAgICAgICAgICAgICAgYW5ndWxhci5mb3JFYWNoKG1vZHVsZSwgbSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkTGlzdC5wdXNoKHNlbGYubG9hZChtLCBwYXJhbXMpKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgcHJvbWlzZSBvbmNlIGV2ZXJ5dGhpbmcgaGFzIGxvYWRlZFxyXG4gICAgICAgICAgICAgICAgICAgICRxLmFsbChkZWZlcnJlZExpc3QpLnRoZW4ocmVzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShyZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sIGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgb3IgU2V0IGEgY29uZmlndXJhdGlvbiBkZXBlbmRpbmcgb24gd2hhdCB3YXMgcGFzc2VkIGluXHJcbiAgICAgICAgICAgICAgICBpZihhbmd1bGFyLmlzU3RyaW5nKG1vZHVsZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25maWcgPSBzZWxmLmdldE1vZHVsZUNvbmZpZyhtb2R1bGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmKCFjb25maWcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXM6IFttb2R1bGVdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmKGFuZ3VsYXIuaXNPYmplY3QobW9kdWxlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNhc2Uge3R5cGU6ICdqcycsIHBhdGg6IGxhenlMb2FkVXJsICsgJ3Rlc3RNb2R1bGUuZmFrZWpzJ31cclxuICAgICAgICAgICAgICAgICAgICBpZihhbmd1bGFyLmlzRGVmaW5lZChtb2R1bGUucGF0aCkgJiYgYW5ndWxhci5pc0RlZmluZWQobW9kdWxlLnR5cGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzOiBbbW9kdWxlXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZyA9IHNlbGYuc2V0TW9kdWxlQ29uZmlnKG1vZHVsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmKGNvbmZpZyA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtb2R1bGVOYW1lID0gc2VsZi5fZ2V0TW9kdWxlTmFtZShtb2R1bGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVyclRleHQgPSBgTW9kdWxlIFwiJHsgbW9kdWxlTmFtZSB8fCAndW5rbm93bicgfVwiIGlzIG5vdCBjb25maWd1cmVkLCBjYW5ub3QgbG9hZC5gO1xyXG4gICAgICAgICAgICAgICAgICAgICRkZWxlZ2F0ZS5fJGxvZy5lcnJvcihlcnJUZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QobmV3IEVycm9yKGVyclRleHQpKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZGVwcmVjYXRlZFxyXG4gICAgICAgICAgICAgICAgICAgIGlmKGFuZ3VsYXIuaXNEZWZpbmVkKGNvbmZpZy50ZW1wbGF0ZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoYW5ndWxhci5pc1VuZGVmaW5lZChjb25maWcuZmlsZXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcuZmlsZXMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihhbmd1bGFyLmlzU3RyaW5nKGNvbmZpZy50ZW1wbGF0ZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy5maWxlcy5wdXNoKGNvbmZpZy50ZW1wbGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZihhbmd1bGFyLmlzQXJyYXkoY29uZmlnLnRlbXBsYXRlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLmZpbGVzLmNvbmNhdChjb25maWcudGVtcGxhdGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHZhciBsb2NhbFBhcmFtcyA9IGFuZ3VsYXIuZXh0ZW5kKHt9LCBwYXJhbXMsIGNvbmZpZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gaWYgc29tZW9uZSB1c2VkIGFuIGV4dGVybmFsIGxvYWRlciBhbmQgY2FsbGVkIHRoZSBsb2FkIGZ1bmN0aW9uIHdpdGgganVzdCB0aGUgbW9kdWxlIG5hbWVcclxuICAgICAgICAgICAgICAgIGlmKGFuZ3VsYXIuaXNVbmRlZmluZWQoY29uZmlnLmZpbGVzKSAmJiBhbmd1bGFyLmlzRGVmaW5lZChjb25maWcubmFtZSkgJiYgJGRlbGVnYXRlLm1vZHVsZUV4aXN0cyhjb25maWcubmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGRlbGVnYXRlLmluamVjdChjb25maWcubmFtZSwgbG9jYWxQYXJhbXMsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICRkZWxlZ2F0ZS5maWxlc0xvYWRlcihjb25maWcsIGxvY2FsUGFyYW1zKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAkZGVsZWdhdGUuaW5qZWN0KG51bGwsIGxvY2FsUGFyYW1zKS50aGVuKHJlcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocmVzKTtcclxuICAgICAgICAgICAgICAgICAgICB9LCBlcnIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0sIGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8vIHJldHVybiB0aGUgcGF0Y2hlZCBzZXJ2aWNlXHJcbiAgICAgICAgICAgIHJldHVybiAkZGVsZWdhdGU7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHJcbn0pKGFuZ3VsYXIpO1xyXG4iXX0=